package com.prb.framework.factory;

import com.prb.framework.annotation.PrbSecurity;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JurProxyFactory {

    /**
     * jdk 代理
     * @param object
     * @return
     */
    public static Object getJdkProxy(Object object){

        return Proxy.newProxyInstance(JurProxyFactory.class.getClassLoader(), object.getClass().getInterfaces(), (proxy, method, args) -> {

            Object result;

            String role;
            Boolean canAccess = false;

            Class<?> clazz = object.getClass();
            PrbSecurity clazzAnnotation = clazz.getAnnotation(PrbSecurity.class);

            Method method1 = clazz.getMethod(method.getName(), method.getParameterTypes());

            PrbSecurity security = method1.getAnnotation(PrbSecurity.class);

            if(clazzAnnotation == null && security == null){
                return method.invoke(object , args);
            }else if(security != null){
                role = security.value();
            }else{
                role = clazzAnnotation.value();
            }
            for (Object arg : args) {
                if (arg.equals(role)) {
                    canAccess = true;
                    break;
                }
            }

            if(!canAccess){
                return "no jur access";
            }

            result = method.invoke(object , args);
            return result;
        });
    }

    /**
     * cglib 代理
     * @param object
     * @return
     */
    public static Object getCglibProxy(Object object){

        return Enhancer.create(object.getClass(), (MethodInterceptor) (o, method, objects, methodProxy) -> {


            String role;
            Boolean canAccess = false;
            Object result;

            Class<?> clazz = object.getClass();

            Method method1 = clazz.getMethod(method.getName(), method.getParameterTypes());
            System.out.println("=====");
            PrbSecurity security = method1.getAnnotation(PrbSecurity.class);

            PrbSecurity clazzAnnotation = clazz.getAnnotation(PrbSecurity.class);

            if(security == null && clazzAnnotation == null){
                return method.invoke(object , objects);

            }else if(security != null){
                role = security.value();
                System.out.println("========================");
            }else{
                role = clazzAnnotation.value();
            }
            for (Object arg : objects) {
                if (arg.equals(role)) {
                    canAccess = true;
                    break;
                }
            }

            if(!canAccess){
                return "can not access";
            }

            result = method.invoke(object , objects);
            return result;
        });
    }


}
